﻿namespace TestTool.GUI.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.IO.IsolatedStorage;
    using System.Xml.Serialization;
    using TestTool.GUI.Data;
    using TestTool.GUI.Enums;
    using TestTool.GUI.Views;
    using TestTool.Tests.Definitions.Data;
    using TestTool.Tests.Definitions.UI;
    using TestTool.Tests.Engine;

    internal class MainController : Controller<IMainView>
    {
        private IController _activeController;
        private ConformanceTestController _conformanceTestController;
        private List<IController> _controllers;
        private const string _dataFileName = "Context.xml";
        private DeviceController _deviceController;
        private DiscoveryController _discoveryController;
        private ManagementController _managementController;
        private TestController _testController;

        public MainController(IMainView view) : base(view)
        {
            ContextController.InitGeneralContext();
        }

        private void _conformanceTestController_SettingsMissing(object sender, SettingsMissingEventArgs e)
        {
            base.View.ActivateManagementPage();
            this._managementController.ShowSettings(e.Settings);
        }

        private void _deviceController_OperationCompleted()
        {
            this.SwitchToIdle();
        }

        private void _deviceController_OperationStarted()
        {
            foreach (IController controller in this._controllers)
            {
                controller.SwitchToState(TestTool.GUI.Enums.ApplicationState.CommandRunning);
            }
            this.SwitchToState(TestTool.GUI.Enums.ApplicationState.CommandRunning);
        }

        private void _discoveryController_DiscoveryCompleted()
        {
            this.SwitchToIdle();
        }

        private void _discoveryController_DiscoveryStarted()
        {
            foreach (IController controller in this._controllers)
            {
                controller.SwitchToState(TestTool.GUI.Enums.ApplicationState.DiscoveryRunning);
            }
            this.SwitchToState(TestTool.GUI.Enums.ApplicationState.DiscoveryRunning);
        }

        private void _managementController_OnOperationCompleted()
        {
            this.SwitchToIdle();
        }

        private void _managementController_OnOperationStarted()
        {
            foreach (IController controller in this._controllers)
            {
                controller.SwitchToState(TestTool.GUI.Enums.ApplicationState.CommandRunning);
            }
            this.SwitchToState(TestTool.GUI.Enums.ApplicationState.CommandRunning);
        }

        private void _managementController_ProfileApplied(Profile profile)
        {
            this._testController.ApplyProfile(profile);
        }

        private void _managementController_SettingsLoaded(object sender, EventArgs e)
        {
            this._discoveryController.UpdateView();
            this._conformanceTestController.UpdateView();
        }

        private void _testController_DeviceInfoReceived(DeviceInfo info)
        {
            this._conformanceTestController.DisplayDeviceInfo(info);
        }

        private void _testController_SettingPagesLoaded(List<SettingsTabPage> pages)
        {
            this._managementController.AddSettingsPages(pages);
        }

        private void _testController_TestsCleared()
        {
            this._conformanceTestController.Clear();
        }

        private void _testController_TestSuiteCompleted(bool bCompletedNormally)
        {
            this.SwitchToIdle();
        }

        private void _testController_TestSuiteStarted(TestSuiteParameters obj, bool conformance)
        {
            foreach (IController controller in this._controllers)
            {
                controller.SwitchToState(conformance ? TestTool.GUI.Enums.ApplicationState.ConformanceTestRunning : TestTool.GUI.Enums.ApplicationState.TestRunning);
            }
            this.SwitchToState(conformance ? TestTool.GUI.Enums.ApplicationState.ConformanceTestRunning : TestTool.GUI.Enums.ApplicationState.TestRunning);
        }

        public void ActivateController(IController controller)
        {
            if (this._activeController != null)
            {
                this._activeController.UpdateContext();
            }
            controller.UpdateView();
            controller.UpdateViewFunctions();
            this._activeController = controller;
        }

        public override void Initialize()
        {
            foreach (IController controller in this._controllers)
            {
                controller.Initialize();
            }
        }

        public void LoadContext()
        {
            try
            {
                this.LoadContextData();
            }
            catch (Exception)
            {
            }
            this.OnPostLoadContextData();
        }

        public void LoadContextData()
        {
            Stream stream = null;
            IsolatedStorageFile machineStoreForAssembly = IsolatedStorageFile.GetMachineStoreForAssembly();
            stream = new IsolatedStorageFileStream("Context.xml", FileMode.Open, machineStoreForAssembly);
            SavedContext context = null;
            StreamReader textReader = new StreamReader(stream);
            XmlSerializer serializer = new XmlSerializer(typeof(SavedContext));
            context = serializer.Deserialize(textReader) as SavedContext;
            textReader.Close();
            if (context != null)
            {
                foreach (IController controller in this._controllers)
                {
                    controller.LoadSavedContext(context);
                }
            }
        }

        public void OnPostLoadContextData()
        {
            this._managementController.OnPostLoadContextData();
        }

        public bool RequestInProgress()
        {
            if (!this._deviceController.RequestPending && !this._conformanceTestController.RequestPending)
            {
                return this._discoveryController.RequestPending;
            }
            return true;
        }

        public void SaveContextData()
        {
            IsolatedStorageFile machineStoreForAssembly = IsolatedStorageFile.GetMachineStoreForAssembly();
            IsolatedStorageFileStream stream = new IsolatedStorageFileStream("Context.xml", FileMode.Create, machineStoreForAssembly);
            StreamWriter writer = new StreamWriter(stream);
            XmlSerializer serializer = new XmlSerializer(typeof(SavedContext));
            SavedContext o = new SavedContext();
            this._conformanceTestController.UpdateContext();
            o.SetupInfo = ContextController.GetSetupInfo();
            this._discoveryController.UpdateContext();
            DiscoveredDevices discoveredDevices = ContextController.GetDiscoveredDevices();
            if (discoveredDevices != null)
            {
                o.DiscoveryContext = new SavedDiscoveryContext();
                o.DiscoveryContext.ServiceAddress = discoveredDevices.ServiceAddress;
                o.DiscoveryContext.DeviceAddress = (discoveredDevices.DeviceAddress != null) ? discoveredDevices.DeviceAddress.ToString() : string.Empty;
                o.DiscoveryContext.SearchScopes = discoveredDevices.SearchScopes.Replace(Environment.NewLine, " ");
                o.DiscoveryContext.ShowSearchOptions = discoveredDevices.ShowSearchOptions;
                if ((discoveredDevices.NIC != null) && (discoveredDevices.NIC.IP != null))
                {
                    o.DiscoveryContext.InterfaceAddress = discoveredDevices.NIC.IP.ToString();
                }
            }
            this._managementController.UpdateContext();
            o.DeviceEnvironment = ContextController.GetDeviceEnvironment();
            this._deviceController.UpdateContext();
            o.RequestsInfo = ContextController.GetRequestsInfo();
            o.MediaInfo = ContextController.GetMediaInfo();
            o.PTZInfo = ContextController.GetPTZInfo();
            o.DebugInfo = ContextController.GetDebugInfo();
            serializer.Serialize((TextWriter) writer, o);
            writer.Close();
        }

        public void SetChildControllers(ConformanceTestController setupController, DiscoveryController discoveryController, ManagementController managementController, TestController testController, DeviceController deviceController)
        {
            this._conformanceTestController = setupController;
            this._discoveryController = discoveryController;
            this._managementController = managementController;
            this._testController = testController;
            this._deviceController = deviceController;
            this._controllers = new List<IController>();
            this._controllers.AddRange(new IController[] { setupController, discoveryController, managementController, testController, deviceController });
            this._testController.TestSuiteStarted += new Action<TestSuiteParameters, bool>(this._testController_TestSuiteStarted);
            this._testController.TestSuiteCompleted += new Action<bool>(this._testController_TestSuiteCompleted);
            this._testController.TestsCleared += new Action(this._testController_TestsCleared);
            this._testController.SettingPagesLoaded += new Action<List<SettingsTabPage>>(this._testController_SettingPagesLoaded);
            this._managementController.ProfileApplied += new Action<Profile>(this._managementController_ProfileApplied);
            this._managementController.OperationStarted += new Action(this._managementController_OnOperationStarted);
            this._managementController.OperationCompleted += new Action(this._managementController_OnOperationCompleted);
            this._managementController.SettingsLoaded += new EventHandler(this._managementController_SettingsLoaded);
            this._discoveryController.DiscoveryStarted += new Action(this._discoveryController_DiscoveryStarted);
            this._discoveryController.DiscoveryCompleted += new Action(this._discoveryController_DiscoveryCompleted);
            this._conformanceTestController.OperationStarted += new Action(this._deviceController_OperationStarted);
            this._conformanceTestController.OperationCompleted += new Action(this._deviceController_OperationCompleted);
            this._discoveryController.OperationStarted += new Action(this._deviceController_OperationStarted);
            this._discoveryController.OperationCompleted += new Action(this._deviceController_OperationCompleted);
            this._deviceController.OperationStarted += new Action(this._deviceController_OperationStarted);
            this._deviceController.OperationCompleted += new Action(this._deviceController_OperationCompleted);
            this._conformanceTestController.TestsRunRequested += new Action(this._testController.RunConformance);
            this._conformanceTestController.HaltRequested += new Action(this._testController.Halt);
            this._conformanceTestController.ExitRequested += new Action(this._testController.Exit);
            this._conformanceTestController.SettingsMissing += new EventHandler<SettingsMissingEventArgs>(this._conformanceTestController_SettingsMissing);
            this._testController.TestStarted += new Action<TestInfo>(this._conformanceTestController.TestStarted);
            this._testController.TestCompleted += new Action<TestInfo, TestTool.Tests.Definitions.Trace.TestLog>(this._conformanceTestController.TestCompleted);
            this._testController.TestSuiteCompleted += new Action<bool>(this._conformanceTestController.TestSuiteCompleted);
            this._testController.ConformanceInitializationCompleted += new Action<ConformanceInitializationData>(this._conformanceTestController.InitializationCompleted);
            this._testController.DeviceInfoReceived += new Action<DeviceInfo>(this._testController_DeviceInfoReceived);
        }

        public void StopRequest()
        {
            foreach (IController controller in new IController[] { this._deviceController, this._conformanceTestController, this._discoveryController })
            {
                if (controller.RequestPending)
                {
                    controller.Stop();
                }
            }
        }

        public void StopTest()
        {
            if (this._testController.Running)
            {
                this._testController.Exit();
            }
            if (this._conformanceTestController.Running)
            {
                this._conformanceTestController.Exit();
            }
        }

        private void SwitchToIdle()
        {
            foreach (IController controller in this._controllers)
            {
                controller.SwitchToState(TestTool.GUI.Enums.ApplicationState.Idle);
            }
            this.SwitchToState(TestTool.GUI.Enums.ApplicationState.Idle);
        }

        public bool TestIsRunning()
        {
            if (!this._testController.Running)
            {
                return this._conformanceTestController.Running;
            }
            return true;
        }
    }
}

